package com.cardmanager.pro.business.impl;

import java.math.BigDecimal;
import java.util.*;

import javax.persistence.EntityManager;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.CommonsUtil;
import com.cardmanager.pro.pojo.ConsumeTaskPOJO;
import com.cardmanager.pro.repository.ConsumeTaskPOJORepository;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;
import com.cardmanager.pro.pojo.RepaymentTaskPOJO;
import com.cardmanager.pro.repository.RepaymentTaskPOJORepository;

import cn.jh.common.utils.DateUtil;
@Service
public class RepaymentTaskPOJOBusinessImpl implements RepaymentTaskPOJOBusiness {
	@Autowired
	private RepaymentTaskPOJORepository repaymentTaskPOJORepository;

	@Autowired
	private ConsumeTaskPOJORepository consumeTaskPOJORepository;

	@Autowired
	private EntityManager em;

	@Autowired
	private JdbcTemplate jdbcTemplate;


	@Override
	public List<Object[]> queryRepaymentTaskAllamountByUserIdAndCardno(String userId, String creditCardNumber) {
		List<Object[]> objects =  repaymentTaskPOJORepository.queryRepaymentTaskAllamountByUserIdAndCardno(userId, creditCardNumber);
		return objects;
	}
	@Transactional
	@Override
	public RepaymentTaskPOJO save(RepaymentTaskPOJO repaymentTaskPOJO) {
		RepaymentTaskPOJO model = repaymentTaskPOJORepository.save(repaymentTaskPOJO);
		em.flush();
		em.clear();
		return model;
	}

	@Override
	public int queryTaskStatus0Count(String userIdStr, String creditCardNumber, int taskStatus) {
		return repaymentTaskPOJORepository.queryTaskStatusCount(userIdStr,creditCardNumber,taskStatus);
	}

	/**
	 * 获取交易等待执行的任务
	 * @return
	 */
	@Override
	public List<RepaymentTaskPOJO> findTaskType2AndTaskStatus0RepaymentTaskPay() {
		Date nowDate = new Date();
		String nowDateTime = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd HH:mm:ss");
		String nowDateString = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd");
		//获取小等于当前时间等待执行的任务
		List<RepaymentTaskPOJO> list = repaymentTaskPOJORepository.findTaskTypeAndTaskStatusRepaymentTaskPay(nowDateTime,nowDateString);
		if(list.size() > 0 ){
			for(RepaymentTaskPOJO pojo : list){
				pojo.setTaskStatus(6);
				//更新待执行状态的任务，避免二次定时任务重复消费或还款；
				repaymentTaskPOJORepository.save(pojo);
			}
		}
		return list;
	}

	/**
	 * 获取代还等待执行的任务
	 * @return
	 */
	@Transactional
	@Override
	public List<RepaymentTaskPOJO> findTaskType2AndTaskStatus0RepaymentTask() {
		Date nowDate = new Date();
		String nowDateTime = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd HH:mm:ss");
		String nowDateString = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd");
		//获取小等于当前时间等待执行的任务
		List<RepaymentTaskPOJO> list = repaymentTaskPOJORepository.findTaskTypeAndTaskStatusRepaymentTask(nowDateTime,nowDateString);
		if(list.size() > 0 ){
			Iterator<RepaymentTaskPOJO> iterator = list.iterator();
			while (iterator.hasNext()) {
				RepaymentTaskPOJO pojo = iterator.next();
				//查询是否有失败的订单
				List<RepaymentTaskPOJO> result = repaymentTaskPOJORepository.findPayStatus(nowDateTime,nowDateString,pojo.getCreditCardNumber());
				if (result.size() > 0) {
					//查询成功的订单，并保存到异常还款表；
					RepaymentTaskPOJO onPojo = repaymentTaskPOJORepository.findPayStatusOn(nowDateTime, nowDateString, pojo.getCreditCardNumber());

					if (onPojo != null) {
						ConsumeTaskPOJO cun = new ConsumeTaskPOJO();
						cun.setOrderCode(onPojo.getOrderNo());
						cun.setTaskStatus(0);
						cun.setUserId(onPojo.getUserId());
						cun.setRealAmount(onPojo.getRealAmount());
						cun.setAmount(onPojo.getAmount());
						cun.setTaskType(onPojo.getTaskType());
						cun.setExecuteDate(onPojo.getExecuteDate());
						cun.setChannelTag(onPojo.getChannelTag());
						cun.setChannelId(onPojo.getChannelId());
						cun.setRate(onPojo.getRate());
						cun.setTotalServiceCharge(onPojo.getTotalServiceCharge());
						cun.setCreditCardNumber(onPojo.getCreditCardNumber());
						cun.setRepaymentTaskId(String.valueOf(onPojo.getId()));
						//更新当前表关联后续代还计划失败
						consumeTaskPOJORepository.save(cun);
						String sql = "update t_repayment_task set task_status = 4 where task_status <> 1 and credit_card_number = " + pojo.getCreditCardNumber() + " and order_no = " + pojo.getOrderNo();
						jdbcTemplate.update(sql);
					}
					iterator.remove();
				} else {
					pojo.setTaskStatus(6);
					//更新待执行状态的任务，避免二次定时任务重复消费或还款；
					repaymentTaskPOJORepository.save(pojo);
				}
			}
		}
		return list;
	}

	/**
	 * 获取交易等待执行的任务
	 * @param userId
	 * @param creditCardNumber
	 * @return
	 */
	@Transactional
	public List<RepaymentTaskPOJO> findTaskTypeAndTaskStatus(String userId,String creditCardNumber) {
		Date nowDate = new Date();
		String nowDateTime = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd HH:mm:ss");
		String nowDateString = DateUtil.getDateStringConvert(new String(), nowDate, "yyyy-MM-dd");
		List<RepaymentTaskPOJO> list = repaymentTaskPOJORepository.findTaskStatus(nowDateTime,nowDateString,userId,creditCardNumber);
		if(list.size() > 0 ){
			for(RepaymentTaskPOJO pojo : list){
				pojo.setTaskStatus(6);
				//更新待执行状态的任务，避免二次定时任务重复消费；
				repaymentTaskPOJORepository.save(pojo);
			}
		}
		return list;
	}

	@Override
	public int queryTaskStatus0AndTaskType0Count(String userId, String creditCardNumber, int taskStatus, int taskType) {
		return repaymentTaskPOJORepository.queryTaskStatusAndTaskTypeCount(userId,creditCardNumber,taskStatus,taskType);
	}

	@Override
	public int queryOrderStatus1AndTaskType0Count(String userId, String creditCardNumber, int orderStatus,int taskType) {
		return repaymentTaskPOJORepository.queryOrderStatusAndTaskTypeCount(userId,creditCardNumber,orderStatus,taskType);
	}

	@Override
	@Transactional
	public RepaymentTaskPOJO[] saveArray(RepaymentTaskPOJO[] repaymentTaskPOJOs) {
		for(int i = 0;i < repaymentTaskPOJOs.length;i++){
			repaymentTaskPOJOs[i] = repaymentTaskPOJORepository.save(repaymentTaskPOJOs[i]);
		}
		return repaymentTaskPOJOs;
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByTaskStatus0RepaymentTask(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByTaskStatusRepaymentTask(userId,creditCardNumber,0,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByTaskStatus1AndOrderStatus0RepaymentTask(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByTaskStatusAndOrderStatusRepaymentTask(userId,creditCardNumber,1,0,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByTaskStatus1AndOrderStatus1RepaymentTask(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByTaskStatusAndOrderStatusRepaymentTask(userId,creditCardNumber,1,1,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByTaskStatus2AndOrderStatus1RepaymentTask(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByTaskStatusAndOrderStatusRepaymentTask(userId,creditCardNumber,2,1,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByTaskStatus2AndOrderstatus0RepaymentTask(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByTaskStatusAndOrderStatusRepaymentTask(userId,creditCardNumber,2,0,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByUserIdAndCreditCardNumber(String userId, String creditCardNumber,
			Pageable pageable) {
		return repaymentTaskPOJORepository.findByUserIdAndCreditCardNumber(userId,creditCardNumber,pageable);
	}

	public List<RepaymentTaskPOJO> findByUserIdAndCreditCardNumberAnAndChannelId( String userId, String creditCardNumber,String channelId){
		return repaymentTaskPOJORepository.findByUserIdAndCreditCardNumberAnAndChannelId(userId,creditCardNumber,channelId);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public RepaymentTaskPOJO findByRepaymentTaskId(String repaymentTaskId) {
		RepaymentTaskPOJO model = repaymentTaskPOJORepository.findByRepaymentTaskId(repaymentTaskId);
		if(model !=null){
			model.setCreateTime(model.getCreateTime().substring(0, model.getCreateTime().lastIndexOf(".")));
			model.setExecuteDateTime(model.getExecuteDateTime().substring(0, model.getExecuteDateTime().lastIndexOf(".")));
		}
		return model;
	}

	@Override
	public RepaymentTaskPOJO findByOrderCode(String orderCode) {
		return repaymentTaskPOJORepository.findByOrderCode(orderCode);
	}

	@Transactional
	@Override
	public void updateTaskStatus4AndReturnMessageByRepaymentTaskId(String repaymentTaskId, String returnMessage) {
		RepaymentTaskPOJO repaymentTaskPOJO = repaymentTaskPOJORepository.findByRepaymentTaskId(repaymentTaskId);
		if(repaymentTaskPOJO!=null){
			repaymentTaskPOJO.setRealAmount(BigDecimal.ZERO);
			repaymentTaskPOJO.setTaskStatus(4);
			repaymentTaskPOJO.setReturnMessage(returnMessage);
			repaymentTaskPOJO = repaymentTaskPOJORepository.save(repaymentTaskPOJO);
		}
	}
	public List<RepaymentTaskPOJO> findRepaymentTask(String userId, String creditCardNumber, String status,String type){
		String sql = "select * from t_repayment_task where user_id = " + userId;
		if(StringUtils.isNotBlank(creditCardNumber)){
			sql += " and credit_card_number = " + creditCardNumber ;
		}
		if(StringUtils.isNotBlank(status)){
			sql += " and task_status = " + status;
		}
		if(StringUtils.isNotBlank(type)){
			if(type.equals("3")){
				sql += " and task_type = 3";
			}else{
				sql += " and task_type <> 3";
			}
		}else{
			sql += " and task_type <> 3";
		}

		List<RepaymentTaskPOJO> result = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(RepaymentTaskPOJO.class));
		return result;
	}

	/**
	 * 查询代还列表和详细计划
	 * @param userId 用户ID
	 * @param creditCardNumber 银行卡号
	 * @param status 订单状态
	 * @param type 订单类型
	 * @param orderNo 订单号
	 * @param pageable
	 * @return
	 */
	public Map<String,Object> findRepaymentList(String userId, String creditCardNumber, String status,String type,String orderNo,
													 Pageable pageable ){
		StringBuilder sql = new StringBuilder();
		sql.append("select * from t_repayment_task where user_id = " + userId);
		if(StringUtils.isNotBlank(creditCardNumber)){
			sql.append(" and credit_card_number = " + creditCardNumber) ;
		}

		if(StringUtils.isNotBlank(status)){
			sql.append(" and task_status = " + status);
		}

		if(StringUtils.isNotBlank(orderNo)){
			sql.append(" and order_no = " + orderNo);
		}

		if(StringUtils.isNotBlank(type)){
			sql.append(" and task_type <> 3");
		}else{
			sql.append(" and task_type = 3");
		}
		List<RepaymentTaskPOJO> count = jdbcTemplate.query(sql.toString(),new BeanPropertyRowMapper<>(RepaymentTaskPOJO.class));

		sql.append(" order by create_time desc limit " + pageable.getOffset() + "," + pageable.getPageSize());
		List<RepaymentTaskPOJO> result = jdbcTemplate.query(sql.toString(),new BeanPropertyRowMapper<>(RepaymentTaskPOJO.class));
		Page<RepaymentTaskPOJO> page ;
		if (count.size() < 1) {
			List<RepaymentTaskPOJO> resultList = new ArrayList<>();
			page = new PageImpl<>(resultList, pageable, 0);
		} else {
			page = new PageImpl<>(result, pageable, count.size());
		}
		Map<String,Object> map = new HashMap<>();
		BigDecimal consumeAmount = BigDecimal.ZERO;
		BigDecimal repaymentAmount = BigDecimal.ZERO;
		for(RepaymentTaskPOJO pojo : result){
			if(pojo.getTaskType() == 3){
				consumeAmount = consumeAmount.add(pojo.getAmount());
				repaymentAmount = repaymentAmount.add(pojo.getRealAmount());
			}
		}
		map.put("consumeAmount", consumeAmount);
		map.put("repaymentAmount", repaymentAmount);
		map.put("page",page);
		Map<String,Object> pram = new HashMap<>();
		pram.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		pram.put(CommonConstants.RESULT, map);
		pram.put(CommonConstants.RESP_MESSAGE, "查询成功");
		return pram;
	}


	@Transactional
	@Override
	public RepaymentTaskPOJO createNewRepaymentTaskPOJO(BigDecimal amount, String userId, String creditCardNumber,int taskType, String description,String createTime,BigDecimal serviceCharge,BigDecimal rate,BigDecimal returnServiceCharge,String channelId,String channelTag) {
		RepaymentTaskPOJO repaymentTaskPOJO = new RepaymentTaskPOJO();
		Date nowTime = new Date();
		Random random = new Random();
		repaymentTaskPOJO.setAmount(amount);
		repaymentTaskPOJO.setRealAmount(amount);
		repaymentTaskPOJO.setRate(rate);
		repaymentTaskPOJO.setChannelId(channelId);
		repaymentTaskPOJO.setChannelTag(channelTag);
		repaymentTaskPOJO.setServiceCharge(serviceCharge);
		repaymentTaskPOJO.setUserId(userId);
		repaymentTaskPOJO.setReturnServiceCharge(returnServiceCharge);
		repaymentTaskPOJO.setRepaymentTaskId(DateUtil.getDateStringConvert(new String(), nowTime,"yyyyMMddHHSSS")+random.nextInt(9)+random.nextInt(9)+random.nextInt(9)+random.nextInt(9)+"1");
		repaymentTaskPOJO.setCreditCardNumber(creditCardNumber);
		repaymentTaskPOJO.setDescription(description);
		repaymentTaskPOJO.setCreateTime(createTime);
		repaymentTaskPOJO.setExecuteDate(DateUtil.getDateStringConvert(new String(), nowTime,"yyyy-MM-dd"));
		repaymentTaskPOJO.setExecuteDateTime(DateUtil.getDateStringConvert(new String(), nowTime,"yyyy-MM-dd HH:ss:mm"));
		repaymentTaskPOJO.setTaskType(taskType);
		repaymentTaskPOJO = repaymentTaskPOJORepository.save(repaymentTaskPOJO);
		return repaymentTaskPOJO;
	}

	@Override
	public RepaymentTaskPOJO findByTaskType0AndTaskStatus0RepaymentTaskPOJO(String userId, String creditCardNumber) {
		return repaymentTaskPOJORepository.findByTaskTypeAndTaskStatusRepaymentTaskPOJO(userId,creditCardNumber,0,0);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<Object[]> findByCreateTime(String userId, String creditCardNumber,Pageable pageable) {
		return repaymentTaskPOJORepository.findByCreateTime(userId,creditCardNumber,pageable);
	}

	@Override
	public List<RepaymentTaskPOJO> findByCreateTime(String userId, String creditCardNumber, String createTime) {
		List<RepaymentTaskPOJO> models = repaymentTaskPOJORepository.findByCreateTime(userId, creditCardNumber,createTime);
		if(models != null && models.size() >0){
			for(RepaymentTaskPOJO model:models){
				model.setCreateTime(model.getCreateTime().substring(0,model.getCreateTime().lastIndexOf(".")));
				model.setExecuteDateTime(model.getExecuteDateTime().substring(0, model.getExecuteDateTime().lastIndexOf(".")));
			}
		}
		return models; 
	}

	@Override
	public int findByOrderStatus1AndTaskType0Count(String userId, String creditCardNumber) {
		return repaymentTaskPOJORepository.findByOrderStatusAndTaskTypeCount(userId,creditCardNumber,1,0);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<Object[]> findByCreateTimeAndTaskStatus1(String userId, String creditCardNumber,Pageable pageable) {
		return repaymentTaskPOJORepository.findByCreateTimeAndTaskStatus(userId,creditCardNumber,1,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<Object[]> findByCreateTimeAndTaskStatus2(String userId, String creditCardNumber,Pageable pageable) {
		return repaymentTaskPOJORepository.findByCreateTimeAndTaskStatus(userId,creditCardNumber,2,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<Object[]> findByCreateTimeAndExecuteDate0(String userId, String creditCardNumber,Pageable pageable) {
		String date = DateUtil.getDateStringConvert(new String(), new Date(), "yyyy-MM-dd");
		return repaymentTaskPOJORepository.findByCreateTimeAndExecuteDate0(userId,creditCardNumber,date,pageable);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<Object[]> findByCreateTimeAndExecuteDate1(String userId, String creditCardNumber,Pageable pageable) {
		String date = DateUtil.getDateStringConvert(new String(), new Date(), "yyyy-MM-dd");
		return repaymentTaskPOJORepository.findByCreateTimeAndExecuteDate1(userId, creditCardNumber,date,pageable);
	}

//	不缓存
	@Override
	public List<RepaymentTaskPOJO> findByExecuteDate(String userId, String creditCardNumber) {
		return repaymentTaskPOJORepository.findByExecuteDate(userId, creditCardNumber);
	}

	@Override
	@Cacheable(value = "RepaymentTaskPOJO",keyGenerator="keyGenerator")
	public List<RepaymentTaskPOJO> findByUserId(String userId,Pageable pageable) {
		return repaymentTaskPOJORepository.findByUserId(userId,pageable);
	}



}
